#pragma once

#include "demoscene.service.Scene.h"
#include "service_context.hh"
#include "Position_struct.h"
#include "Role_struct.h"
#include <map>
#include <iostream>
#include <set>

class SynchronizeProxy;

struct SceneBaseInfo {
    std::uint32_t scene_id;
    std::string scene_name;
    std::set<uint64_t> roles;
};

struct RoleBaseInfo {
    std::shared_ptr<SynchronizeProxy> prx;
    Role role;
};

class SceneManager {
    SceneManager();
    ~SceneManager() = default;
    static SceneManager* instance_;
public:
    void SyncScecneRoleData(std::uint64_t role_uid, std::uint32_t scene_id, const Position& pos = Position(), bool is_enter_scene = false);
    void AddScene(std::uint32_t scene_id,const std::string& name);
    bool AddRole(std::uint64_t role_uid, std::uint32_t scene_id,const Position& pos, std::shared_ptr<SynchronizeProxy> prx);
    bool RoleMove(std::uint64_t role_uid, const Position& pos, std::shared_ptr<SynchronizeProxy> prx);
    bool CheckMove(std::uint64_t role_uid, const Position& pos);
    void SetLogger(kratos::service::LoggerPtr);
    std::uint32_t GetRoleSceneId(std::uint64_t role_uid);
public:
    static SceneManager& Instance();
private:
    std::map<std::uint32_t, SceneBaseInfo> scene_info_;
    std::map<std::uint64_t, RoleBaseInfo> role_info_;
    kratos::service::LoggerPtr logger_{ nullptr };
};

class SceneImpl : public Scene {
    kratos::service::LoggerPtr logger_{ nullptr };
public:
//implementation->
    SceneImpl();
    virtual ~SceneImpl();
    virtual bool onAfterFork(rpc::Rpc* rpc) override;
    virtual bool onBeforeDestory(rpc::Rpc* rpc) override;
    virtual void onTick(std::time_t ms) override;
    virtual void onServiceCall(rpc::StubCallPtr callPtr) override;
    virtual void EnterScene(rpc::StubCallPtr call, std::uint64_t, std::int32_t, const Position&) override;
    virtual void Move(rpc::StubCallPtr call, std::uint64_t, const Position&) override;
//implementation<-
};

